package com.one.blocks.rbac.manager;

import com.one.blocks.mvc.exception.BusinessException;
import com.one.blocks.mvc.manager.AbstractBatchManager;
import com.one.blocks.rbac.controller.vo.SysAccountLoginVo;
import com.one.blocks.rbac.domain.SysAccount;
import com.one.blocks.rbac.domain.SysUser;
import com.one.blocks.rbac.enums.RbacResponseEnum;
import com.one.blocks.rbac.mapper.SysAccountMapper;
import com.one.blocks.security.authc.AuthenticateService;
import com.one.blocks.security.authc.SubjectSession;
import com.one.blocks.security.listener.LoginSuccessEvent;
import com.one.blocks.security.listener.LogoutEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author <a href="mailto:idler41@163.con">idler41</a> created on 2022-05-01 10:06:14
 */
@Service
public class SysAccountManager extends AbstractBatchManager<SysAccountMapper, SysAccount> {

    @Autowired
    private SysUserAccountManager sysUserAccountManager;

    @Autowired
    private SysAccountManager sysAccountManager;

    @Autowired
    private SysUserManager sysUserManager;

    @Autowired
    private PasswordManager passwordManager;

    @Autowired
    private AuthenticateService authenticateService;

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    public SysAccountManager(SysAccountMapper mapper) {
        super(mapper);
    }

    public SysAccount getByLoginInfo(String loginInfo) {
        // 手机号码登录

        // 邮箱登录

        // 用户名登录
        return mapper.selectByUsername(loginInfo);
    }

    public SysAccount getDefaultAccount(Integer userId) {
        Integer defaultAccountId = sysUserAccountManager.selectDefaultAccount(userId);
        return sysAccountManager.get(defaultAccountId);
    }

    public SysAccount loginByPassword(SysAccountLoginVo loginAccountVo, HttpServletRequest request, HttpServletResponse response) {
        String rawPassword;
        try {
            rawPassword = passwordManager.decryptPassword(loginAccountVo.getPassword());
        } catch (RuntimeException e) {
            throw new BusinessException(RbacResponseEnum.ILLEGAL_PASSWORD);
        }
        SysAccount sysAccount = mapper.selectByUsername(loginAccountVo.getUsername());
        if (sysAccount != null && passwordManager.match(rawPassword, sysAccount.getPassword())) {
            SysUser sysUser = sysUserManager.getByAccountId(sysAccount.getId());
            applicationContext.publishEvent(new LoginSuccessEvent(this, sysUser.getId(), request, response));
            return sysAccount;
        }
        return null;
    }

    public void logout(HttpServletRequest request) {
        String sessionId = authenticateService.resolveSessionId(request);
        if (sessionId == null) {
            return;
        }
        SubjectSession subjectSession = authenticateService.loadSession(sessionId);
        if (subjectSession != null && subjectSession.getSubjectId() != null) {
            applicationContext.publishEvent(new LogoutEvent(this, subjectSession.getSubjectId(), request));
        }
    }
}